package com.laamella.syntherface.synths.alesis.micron.model;

import com.laamella.syntherface.synths.midi.MidiInterface;
import com.laamella.syntherface.synths.models.MappedDerivedParameterMapper;
import com.laamella.syntherface.synths.models.MappedDerivedParameterModel;
import com.laamella.syntherface.synths.models.NrpnParameterModel;
import com.laamella.syntherface.synths.models.ParameterModel;
import com.laamella.syntherface.synths.models.ParameterType;

public final class Voice {

	public final ParameterModel polyphony;
	public final ParameterModel unison;
	public final ParameterModel unisonDetune;
	public final ParameterModel portamentoEnabled;
	public final ParameterModel portamentoType;
	public final ParameterModel portamentoTime;
	public final ParameterModel pitchwheelType;
	public final ParameterModel analogDrift;
	public final ParameterModel oscillatorSyncType;
	public final MappedDerivedParameterModel oscillatorSyncTypeDerived;
	public final MappedDerivedParameterModel oscillatorSyncHardDerived;
	public final ParameterModel fmAmount;
	public final MappedDerivedParameterModel fmTypeDerived;
	public final MappedDerivedParameterModel fmExponentialDerived;
	public final ParameterModel fmType;
	public final ParameterModel seriesLevel;
	public final ParameterModel noiseType;

	private final static ParameterType PortamentoTimeType = new ParameterType(
			0, 127) {
		@Override
		public String format(int value) {
			return "" + value;
		}
	};

	Voice(final MidiInterface midiInterface) {
		polyphony = new NrpnParameterModel("polyphony", midiInterface, 0,
				new ParameterType.Boolean("monophonic", "polyphonic"));
		unison = new NrpnParameterModel("unison voices", midiInterface, 1,
				new ParameterType.List(new String[] { "off", "2 voices",
						"4 voices", "all voices" }));
		unisonDetune = new NrpnParameterModel("unison detune", midiInterface,
				2, ParameterType.Percentage);
		portamentoEnabled = new NrpnParameterModel("portamento enabled ",
				midiInterface, 3, new ParameterType.List(new String[] { "off",
						"legato", "always" }));
		portamentoType = new NrpnParameterModel("portamento type",
				midiInterface, 4, new ParameterType.List(
						"fixed, scaled, gliss fixed, gliss scaled"));
		portamentoTime = new NrpnParameterModel("portamento time",
				midiInterface, 5, PortamentoTimeType);
		pitchwheelType = new NrpnParameterModel("pitchwheel type",
				midiInterface, 6, new ParameterType.Boolean("held", "all"));
		analogDrift = new NrpnParameterModel("analog drift", midiInterface, 7,
				ParameterType.Percentage);
		oscillatorSyncType = new NrpnParameterModel("oscillator sync type",
				midiInterface, 8, new ParameterType.List(
						"off, hard 2>1, hard 2+3>1, soft 2>1, soft 2+3>1"));
		oscillatorSyncTypeDerived = new MappedDerivedParameterModel(
				"oscillator sync type", new ParameterType.List("hard, soft"));
		oscillatorSyncHardDerived = new MappedDerivedParameterModel(
				"oscillator sync hard", new ParameterType.List(
						"off, hard, soft"));
		new MappedDerivedParameterMapper(
				new int[][] {// 
				{ 0, 0, 0 }, //
						{ 1, 0, 1 }, //
						{ 2, 1, 1 }, //
						{ 3, 0, 2 }, //
						{ 4, 1, 2 }, //
				}, oscillatorSyncType, oscillatorSyncTypeDerived,
				oscillatorSyncHardDerived);

		fmAmount = new NrpnParameterModel("FM amount", midiInterface, 9,
				ParameterType.Promillage);
		fmType = new NrpnParameterModel(
				"FM type",
				midiInterface,
				10,
				new ParameterType.List(
						"lin 2>1, lin 2+3>1, lin 3>2>1, exp 2>1, exp 2+3>1, exp 3>2>1"));
		fmTypeDerived = new MappedDerivedParameterModel("FM type",
				new ParameterType.List("2>1, 2+3>1, 3>2>1"));
		fmExponentialDerived = new MappedDerivedParameterModel(
				"FM exponential", new ParameterType.List("linear, exponential"));

		new MappedDerivedParameterMapper(new int[][] {// 
				{ 0, 0, 0 },//
						{ 1, 1, 0 },//
						{ 2, 2, 0 },//
						{ 3, 0, 1 },//
						{ 4, 1, 1 },//
						{ 5, 2, 1 },//
				}, fmType, fmTypeDerived, fmExponentialDerived);

		seriesLevel = new NrpnParameterModel("series level???", midiInterface,
				41, ParameterType.Percentage);
		noiseType = new NrpnParameterModel("noise type", midiInterface, 42,
				new ParameterType.List("pink, white"));
	}
}
